//
//  Number_public extension.swift
//  boleh
//
//  Created by BO ZHOU on 2020/9/4.
//  Copyright © 2020 BO ZHOU. All rights reserved.
//

import UIKit

protocol NumberProtocol {
    var toString: String { get }
}

extension NumberProtocol {
    
    var toString: String {

        return "\(self)"
    }
}


extension Int: NumberProtocol {
    
    var float_value: CGFloat {
        return CGFloat(self)
    }
    
}


extension Double: NumberProtocol {
    
    /** 四舍五入保留n位小数, 可以传0 */
    func roundTo(places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
    
    var float_value: CGFloat {
        return CGFloat(self)
    }
}

extension CGFloat: NumberProtocol {
    
    /** 四舍五入保留n位小数, 可以传0 */
    func roundTo(places: Int) -> CGFloat {
        let divisor = pow(10.0, CGFloat(places))
        return (self * divisor).rounded() / divisor
    }
    
    /** 角度转数值 */
    static func angle(_ degress: CGFloat) -> CGFloat {
        return CGFloat.pi * degress / 180
    }
    
    /** 数值转小数 */
    var angle_value: CGFloat {
        return self * 180 / CGFloat.pi
    }
    
    /** 转Int */
    var int_value: Int {
        return Int(self)
    }
    
    var double_value: Double {
        return Double(self)
    }
}

private var remainsKey = "remainsKey"

private var remainPercent: CGFloat = 0

public extension CGRect {
    

    /**
     * 判断innerRect是否在self中, 如果不在, 返回偏移量 (mapView的offset)
     */
    func offsetToContainRect(innerRect: CGRect) -> CGSize {
        
        let outerRect = self
        
        // 如果leftOffset > 0, 则需要向右偏移
        // 如果outerRect.minX - innerRect.minX > 0, 则要偏移
        // 如果outerRect.minX - innerRect.minX <= 0, 则不需要向右偏移, 设置为0
        let leftOffset = max(0, outerRect.minX - innerRect.minX)
        
        // 如果rightOffset < 0, 则需要向左偏移
        let rightOffset = min(0, outerRect.maxX - innerRect.maxX)
        
        // 如果topOffset > 0, 则要向下偏移
        let topOffset = max(0, outerRect.minY - innerRect.minY)
        
        // 如果bottomOffset < 0, 则向上偏移
        let bottomOffset = min(0, outerRect.maxY - innerRect.maxY)
        
        return CGSize(width: rightOffset < 0 ? rightOffset : leftOffset, height: topOffset > 0 ? topOffset : bottomOffset)
    }
    
    
    
//    /** 保留多少, 剩余进行缩放 */
//    var remainPercent: CGFloat {
//        get {
//            if let a = objc_getAssociatedObject(self, &remainsKey) as? CGFloat {
//                return a
//            }
//            return 0
//        }
//        set {
//
//            // zwarning: OBJC_ASSOCIATION_ASSIGN 使用这个坑逼, 不能正确存储
//            objc_setAssociatedObject(self, &remainsKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
//        }
//    }
    
    
    /**
     * 缩放时候保留的百分比, 点语法 xxx.remains(remainPercent: 0.6) * 0.7
     */
    mutating func remains(remain: CGFloat) -> CGRect {
        remainPercent = remain
        return self
    }

    /*
     * 围绕中心点缩放
     */
    static func *(left: CGRect, scale: CGFloat) -> CGRect {
        
        let widthScale = left.width * (1 - remainPercent) * scale
        let heightScale = left.height * (1 - remainPercent) * scale
        
        
        return CGRect(x: left.minX + left.width * (1 - remainPercent) * (1-scale)*0.5, y: left.minY + left.height * (1 - remainPercent) * (1 - scale) * 0.5, width: left.width * remainPercent + widthScale, height: left.height * remainPercent + heightScale)

    }
    
    /**
     * 两个frame之间变化的percent计算中间某个percent的frame
     */
    func moveTo(finalFrame: CGRect, percent: CGFloat) -> CGRect {
        
        let x = (finalFrame.minX - self.minX) * percent + self.minX
        let y = (finalFrame.minY - self.minY) * percent + self.minY
        let width = (finalFrame.width - self.width) * percent + self.width
        let height = (finalFrame.height - self.height) * percent + self.height
        
        return CGRect(x: x, y: y, width: width, height: height)
    }

}


public extension CGPoint {
    
    // 给CGPoint扩展减法功能, 两点相减, 返回向量 (相减是不需要考虑坐标系原点的)
    // 因为y轴坐标系和传统数学的坐标系相反, 所以想要获取向量的话是右侧减左侧
    static func -(left: CGPoint, right: CGPoint) -> CGPoint {
        return CGPoint(x: left.x - right.x, y: right.y - left.y)
    }
    
    // 给CGPoint扩展加法功能, 两点相加, 返回向量 (相加, 如果想要返回向量, 需要考虑坐标系原点)
    static func +(left: CGPoint, right: CGPoint) -> CGPoint {
        return CGPoint(x: left.x + right.x, y: left.y - right.y)
    }

    // 获取向量长度
    var vectorLength: CGFloat {
        return sqrt(x*x + y*y)
    }
}
